using System.Globalization;
using System.Text.Json.Serialization;

using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.EntityFrameworkCore;

using ELportal.App.Configuration;
using ELportal.Common.Extensions;
using ELportal.Common.Middlewares;
using ELportal.Repositories;

var builder = WebApplication.CreateBuilder(args);

var appOptions = builder.Configuration
	.GetSection(nameof(AppOptions))
	.Get<AppOptions>();

if (!string.IsNullOrWhiteSpace(appOptions?.Culture))
{
	CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo(appOptions.Culture);
}

if (string.IsNullOrWhiteSpace(appOptions?.ConnectionStringDatabase))
	throw new ArgumentException("Invalid connection string!");

builder.Logging
	.ClearProviders()
	.AddSimpleConsole();

#if DEBUG
	builder.Services.AddCors();
#endif

builder.Services
	.AddOutputCache(x =>
	{
		x.DefaultExpirationTimeSpan = appOptions.Cache.Expiration;
		x.SizeLimit = 1024 * 1024 * appOptions.Cache.SizeMB;
	})
	.AddDbContextPool<UserRepository>(options => options
		.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
		.UseMySQL(appOptions.ConnectionStringDatabase)
	)
	.AddBrotliCompression(appOptions.ResponseCompressionLevel)
	.AddAuthorization()
	.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
	.AddNegotiate();

builder.Services
	.AddMvcCore()
	.AddJsonOptions(opts => opts.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull);

builder.Services.AddHealthChecks();
builder.Services.AddTransient<IUserRepository, UserRepository>();

builder.Host.UseDefaultServiceProvider(options => options.ValidateOnBuild = true);

var app = builder.Build();

#if DEBUG
	app.UseCorsAllowAnyOrigin();
	app.UseDeveloperExceptionPage();
#endif

app
	.UseResponseCompression()
	.UseOutputCache()
	.UseAuthentication()
	.UseAuthorization()
	.UseMiddleware<AuditHandlerMiddleware>()
	.UseHealthChecks(appOptions.HealthCheckPath);

app.MapWhen(x => !x.Request.Path.StartsWithSegments("/api"), builder => builder
	.UseStaticFiles()
	.UseSpa(x => x.Options.DefaultPage = "/index.html"));

app.MapControllerRoute(
	name: "default",
	pattern: "{controller}/{action}");

await app.RunAsync();
